/****
 * 用于创建 springboot 的 controller、service、serviceImpl、mapper 层的文件。
 */

const path = require("path");
const fs = require("fs");
/***
 * 功能函数：>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
 */
const handleDir = path => {
  console.log("path:", path);
  //切分成数组
  let pathList = path.split("/");
  let pathStr = "";
  for (let item of pathList) {
    if (!item) {
      continue;
    }
    pathStr += `/${item}`;
    if (hasDir(pathStr)) {
      continue;
    }

    console.log("pathstr: ", pathStr);
    fs.mkdirSync(pathStr);
  }
};

const hasDir = path => {
  if (fs.existsSync(path)) {
    return true;
  } else {
    return false;
  }
};

function underscoreToCamel(str, isPascal = false) {
  if (typeof str !== "string") {
    throw new TypeError("输入必须为字符串类型");
  }

  // 处理空字符串直接返回
  if (str.length === 0) return "";

  let value = str
    .split("_") // 按 _ 分割单词
    .filter(word => word.length > 0) // 过滤空字符串（处理连续下划线的情况）
    .map((word, index) => {
      // 首个单词的特殊处理
      if (index === 0 && !isPascal) {
        return word.toLowerCase(); // 小驼峰首字母小写
      }
      // 其他单词首字母大写，其余小写
      return word[0].toUpperCase() + word.slice(1).toLowerCase();
    })
    .join("");

  // 核心转换逻辑
  return value; // 拼接结果
}

/***
 * 功能函数：<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,
 */

const datasource = ["'tms_store_group'"];

const rootPath = path.resolve(__dirname, "../build-java/");
//判断是否存在 src, view 目录
handleDir(rootPath);

const createJavaDir = (dirPath, datasource) => {
  // let dirList = ["controller", "service", "serviceImpl", "mapper", "vo", "api"];
  // //创建 controller 文件夹
  // //创建 service 文件夹
  // //创建 serviceImpl 文件夹
  // //创建 mapper 文件夹
  // for (let fileName of dirList) {
  //   const filePath = path.resolve(dirPath, fileName);
  //   handleDir(filePath);
  // }
};

const createJavaFileTempalte = (dirPath, datasource) => {
  for (let fileName of datasource) {
    handleDir(`${dirPath}/api`);
    const apiFilePath = path.resolve(`${dirPath}/api`);

    let index = fileName.indexOf("_");
    let prefix = fileName.substring(0, index);

    fileName = underscoreToCamel(fileName).replace(/(\w)/, v =>
      v.toUpperCase()
    );
    console.log("fileName111111:", fileName);

    let controllerPath = `${dirPath}/${prefix}/controller`;
    handleDir(controllerPath);
    const controllerFilePath = path.resolve(
      `${controllerPath}`,
      `${fileName}Controller.java`
    );

    let servicePath = `${dirPath}/${prefix}/service`;
    handleDir(servicePath);
    const serviceFilePath = path.resolve(
      servicePath,
      `${fileName}Service.java`
    );

    let serviceImplPath = `${dirPath}/${prefix}/service/impl`;
    handleDir(serviceImplPath);
    const serviceImplFilePath = path.resolve(
      serviceImplPath,
      `${fileName}ServiceImpl.java`
    );

    let mapperPath = `${dirPath}/${prefix}/mapper`;
    handleDir(mapperPath);
    const mapperFilePath = path.resolve(mapperPath, `${fileName}Mapper.java`);

    // handleDir(filePath);
    handleApiFileTemplate(apiFilePath, fileName);
    handleControllerFileTemplate(controllerFilePath, fileName);
    handleServiceFileTemplate(serviceFilePath, fileName);
    handleServiceImplFileTemplate(serviceImplFilePath, fileName);
    handleMapperFileTemplate(mapperFilePath, fileName);
  }
};

const handleApiFileTemplate = (filePath, fileName) => {
  //首字母大写的文件名
  const firstUpperCase = fileName.replace(/(\w)/, v => v.toUpperCase());
  //首字母小写的文件名
  const firstLowerCase = fileName.replace(/(\w)/, v => v.toLowerCase());

  // /${firstLowerCase}
  const template = `
import axios, {Axios} from 'axios'
const context = "/ucenter"

/**
 * 获取 ${firstUpperCase} 分页列表
*/
export function get${firstUpperCase}Pagination(data: any) {
  return axios.get(\`\${context}\/${firstLowerCase}/pagination\`, { params: data });
}


/**
 * 获取 ${firstUpperCase} 所有数据
*/
export function get${firstUpperCase}AllList(data: any) {
  return axios.get(\`\${context}\/${firstLowerCase}/all\`, { params: data });
}


/**
 * 获取 ${firstUpperCase} 详情
*/
export function get${firstUpperCase}DetailById(id: any) {
  return axios.get(\`\${context}\/${firstLowerCase}/\${id}\`, { params:{id} });
}


/**
 * 新增 ${firstUpperCase}
*/
export function add${firstUpperCase}(data: any) {
  return axios.post(\`\${context}/${firstLowerCase}\`, data);
}

/**
 * 修改 ${firstUpperCase}
*/
export function update${firstUpperCase}(data: any) {
  return axios.put(\`\${context}/${firstLowerCase}\`, data);
}

/**
 * 删除 ${firstUpperCase}
*/
export function batchRemove${firstUpperCase}(data: any) {
  return axios.post(\`\${context}/${firstLowerCase}/batchRemove\`, data);
}

    `;

  console.log("filePath: ", filePath);

  fs.writeFileSync(
    path.resolve(filePath, `${firstLowerCase}.api.ts`),
    template
  );
};

const handleVoFileTemplate = (filePath, fileName) => {
  //创建  Query, Add, Update
  //首字母大写的文件名
  const firstUpperCase = fileName.replace(/(\w)/, v => v.toUpperCase());
  //首字母小写的文件名
  const firstLowerCase = fileName.replace(/(\w)/, v => v.toLowerCase());

  console.log("handleVoFileTemplate: ", filePath);

  const queryClassName = `${firstUpperCase}Query`;
  const queryInstanceName = `${firstLowerCase}Query`;
  const addClassName = `${firstUpperCase}Vo`;
  const addInstanceName = `${firstLowerCase}Vo`;
  const updateClassName = `${firstUpperCase}Vo`;
  const updateInstanceName = `${firstLowerCase}Vo`;

  const queryClassNameTemplate = `
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class ${queryClassName} {

}
  `;
  const addClassNameTemplate = `
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class ${addClassName} {

}
  `;
  const updateClassNameTemplate = `
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
  public class ${updateClassName} {

  }
  `;

  fs.writeFileSync(
    `${filePath}/${queryClassName}.java`,
    queryClassNameTemplate
  );
  fs.writeFileSync(`${filePath}/${addClassName}.java`, addClassNameTemplate);
  fs.writeFileSync(
    `${filePath}/${updateClassName}.java`,
    updateClassNameTemplate
  );
};

const handleControllerFileTemplate = (filePath, fileName) => {
  //首字母大写的文件名
  const firstUpperCase = fileName.replace(/(\w)/, v => v.toUpperCase());
  //首字母小写的文件名
  const firstLowerCase = fileName.replace(/(\w)/, v => v.toLowerCase());

  console.log("handleControllerFileTemplate: ", firstUpperCase, firstLowerCase);

  const serviceClassName = `${firstUpperCase}Service`;
  const serivceInstanceName = `${firstLowerCase}Service`;
  const queryClassName = `${firstUpperCase}Query`;
  const queryInstanceName = `${firstLowerCase}Query`;
  const addClassName = `${firstUpperCase}Vo`;
  const addInstanceName = `${firstLowerCase}Vo`;
  const updateClassName = `${firstUpperCase}Vo`;
  const updateInstanceName = `${firstLowerCase}Vo`;

  const template = `

@RestController
@RequestMapping("/${firstLowerCase}")
public class ${firstUpperCase}Controller {

    @Resource
    private ${serviceClassName} ${serivceInstanceName};


    /**
     * 获取 ${fileName} 分页列表
     */
    @GetMapping("/pagination")
    public Ret get${firstUpperCase}Pagination( PaginationVo paginationVo, ${queryClassName} ${queryInstanceName} ) throws Exception {
        IPage page = ${serivceInstanceName}.get${firstUpperCase}Pagination(paginationVo, ${queryInstanceName} );
        return Ret.toPage(page);
    }


    /**
     * 获取 ${fileName} 所有数据
     */
    @GetMapping("/all")
    public Ret get${firstUpperCase}AllList( ${queryClassName} ${queryInstanceName} ) throws Exception {
        List<${firstUpperCase}Entity> list = ${serivceInstanceName}.get${firstUpperCase}AllList( ${queryInstanceName} );
        return Ret.ok(list);
    }



    /**
     * 获取 ${fileName} 详情
    */
   @GetMapping("/{id}")
   public Ret get${firstUpperCase}Detail(@PathVariable Long id) throws Exception {

       ${firstUpperCase}Entity ${firstLowerCase} = ${serivceInstanceName}.get${firstUpperCase}Detail(id);
       return Ret.ok(${firstLowerCase});
   }


    /**
     * 新增 ${fileName}
     * */
    @PostMapping("")
    public Ret add${firstUpperCase}(@RequestBody ${addClassName} ${addInstanceName}) throws Exception {

        ${serivceInstanceName}.add${firstUpperCase}(${addInstanceName});
        return Ret.ok();
    }


    /**
     * 更新 ${fileName}
     * */
    @PutMapping("")
    public Ret update${firstUpperCase}(@RequestBody ${updateClassName} ${updateInstanceName}) throws Exception {

        ${serivceInstanceName}.update${firstUpperCase}(${updateInstanceName});
        return Ret.ok();
    }


    /**
     * 删除 ${fileName}
     * */
    @PostMapping("/batchRemove")
    public Ret batchRemove${firstUpperCase}( @RequestBody List<Long> ids ) throws Exception {

        ${firstLowerCase}Service.batchRemove${firstUpperCase}(ids);
        return Ret.ok();
    }
}

  `;
  fs.writeFileSync(filePath, template);
};

const handleServiceFileTemplate = (filePath, fileName) => {
  //首字母大写的文件名
  const firstUpperCase = fileName.replace(/(\w)/, v => v.toUpperCase());
  //首字母小写的文件名
  const firstLowerCase = fileName.replace(/(\w)/, v => v.toLowerCase());

  const serviceClassName = `${firstUpperCase}Service`;
  const serivceInstanceName = `${firstLowerCase}Service`;
  const queryClassName = `${firstUpperCase}Query`;
  const queryInstanceName = `${firstLowerCase}Query`;
  const addClassName = `${firstUpperCase}Vo`;
  const addInstanceName = `${firstLowerCase}Vo`;
  const updateClassName = `${firstUpperCase}Vo`;
  const updateInstanceName = `${firstLowerCase}Vo`;

  const template = `
import org.apache.commons.beanutils.PropertyUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;


public interface ${firstUpperCase}Service {

    /**
     * 获取 ${fileName} 分页列表
     */
    public IPage get${firstUpperCase}Pagination( PaginationVo paginationVo, ${queryClassName} ${queryInstanceName} ) throws Exception;


    /**
     * 获取 ${fileName} 所有数据
     *
    */
    public List<${firstUpperCase}Entity> get${firstUpperCase}AllList( ${queryClassName} ${queryInstanceName} ) throws Exception;


    /**
     * 获取 ${fileName} 详情
    */
    public ${firstUpperCase}Entity get${firstUpperCase}Detail( Long id) throws Exception;


    /**
     * 新增 ${fileName}
     * */
    public void add${firstUpperCase}(${addClassName} ${addInstanceName}) throws Exception;


    /**
     * 更新 ${fileName}
     * */
    public void update${firstUpperCase}( ${updateClassName} ${updateInstanceName}) throws Exception;

    /**
     * 删除 ${fileName}
     * */
    public void batchRemove${firstUpperCase}( List<Long> ids ) throws Exception;

}

      `;
  fs.writeFileSync(filePath, template);
};

const handleServiceImplFileTemplate = (filePath, fileName) => {
  //首字母大写的文件名
  const firstUpperCase = fileName.replace(/(\w)/, v => v.toUpperCase());
  //首字母小写的文件名
  const firstLowerCase = fileName.replace(/(\w)/, v => v.toLowerCase());

  const serviceClassName = `${firstUpperCase}Service`;
  const serivceInstanceName = `${firstLowerCase}Service`;
  const queryClassName = `${firstUpperCase}Query`;
  const queryInstanceName = `${firstLowerCase}Query`;
  const addClassName = `${firstUpperCase}Vo`;
  const addInstanceName = `${firstLowerCase}Vo`;
  const updateClassName = `${firstUpperCase}Vo`;
  const updateInstanceName = `${firstLowerCase}Vo`;

  const template = `
import org.apache.commons.beanutils.PropertyUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;

@Service
public class ${firstUpperCase}ServiceImpl implements ${firstUpperCase}Service  {

    @Resource
    private ${firstUpperCase}Mapper ${firstLowerCase}Mapper;

    /**
     * 获取 ${fileName} 分页列表
     */
    @Transactional
    public IPage get${firstUpperCase}Pagination( PaginationVo paginationVo, ${queryClassName} ${queryInstanceName} ) throws Exception {

        IPage page = new Page( paginationVo.getPageIndex(), paginationVo.getPageSize() );
        LambdaQueryWrapper<${firstUpperCase}Entity> lqs = new LambdaQueryWrapper();
        ${firstLowerCase}Mapper.selectPage(page, lqs);

        List<${firstUpperCase}Entity> record = page.getRecords();
        if( !ObjectUtil.isNotEmptyList(record)){
            return page;
        }
        return null;
    }


    /**
     * 获取 ${fileName} 所有数据
     *
    */
    @Transactional
    public List<${firstUpperCase}Entity> get${firstUpperCase}AllList( ${queryClassName} ${queryInstanceName} ) throws Exception {

        LambdaQueryWrapper<${firstUpperCase}Entity> lqs = new LambdaQueryWrapper();
        List<${firstUpperCase}Entity> list = ${firstLowerCase}Mapper.selectList(lqs);
        return list;
    }


    /**
     * 获取 ${fileName} 详情
    */
    @Transactional
    public ${firstUpperCase}Entity get${firstUpperCase}Detail( Long id) throws Exception {

        ${firstUpperCase}Entity ${firstLowerCase} = ${firstLowerCase}Mapper.selectById(id);
        return ${firstLowerCase};
    }


    /**
     * 新增 ${fileName}
     * */
    @Transactional
    public void add${firstUpperCase}(${addClassName} ${addInstanceName}) throws Exception {

        ${firstUpperCase}Entity ${firstLowerCase} = new ${firstUpperCase}Entity();
        ReflectionCopy.copyProperties( ${firstLowerCase}, ${addInstanceName} );
        ${firstLowerCase}Mapper.insert(${firstLowerCase});
        return;
    }


    /**
     * 更新 ${fileName}
     * */
    @Transactional
    public void update${firstUpperCase}( ${updateClassName} ${updateInstanceName}) throws Exception {

        if( ${updateInstanceName}.getId() == null ){
            throw GlobalException.gen(10021, "id不存在");
        }
        ${firstUpperCase}Entity ${firstLowerCase} = new ${firstUpperCase}Entity();
        ReflectionCopy.copyProperties( ${firstLowerCase}, ${updateInstanceName} );
        ${firstLowerCase}Mapper.updateById(${firstLowerCase});
        return;
    }

    /**
     * 删除 ${fileName}
     * */
    @Transactional
    public void batchRemove${firstUpperCase}( List<Long> ids ) throws Exception {


        if( !ObjectUtil.isNotEmptyList(ids) ){
            throw GlobalException.gen(10011, "要删除的id不存在");
        }
        ${firstLowerCase}Mapper.deleteBatchIds(ids);
    }

}

      `;
  fs.writeFileSync(filePath, template);
};

const handleMapperFileTemplate = (filePath, fileName) => {
  const template = `
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface ${fileName}Mapper extends BaseMapper<${fileName}Entity> {

}
`;
  fs.writeFileSync(filePath, template);
};

createJavaDir(rootPath);
createJavaFileTempalte(rootPath, datasource);
// handleMapperFileTemplate();
